# -*- coding:utf-8 -*-
#!/usr/in/python
import re
class TermFormular():
    def __init__(self):
        chr_pat = '[一-～\w\d]+'
        self.rules_unpack = []
        self.rules_regex = []
        
        # 或许有规则
        self.rule0 = {'pat':'\((#)\)',    'new':'(\\1|)',    'comment':'(A) => (A|)'}
        self.rule0['pat'] = self.rule0['pat'].replace('#', chr_pat)
        
        
        # 去括号规则
        self.rules_unpack.append({'pat':'\((#)\)',    'new':'\\1',    'comment':'(A) => A'})
        self.rules_unpack.append({'pat':'\(\)',    'new':'',    'comment':'() => empty'})
        self.rules_unpack.append({'pat':'^\(([^\(\)]+)\)$',    'new':'\\1',    'comment':'^(A|B|C)$ => A|B|C'})
        self.rules_unpack.append({'pat':'\(\(([^\(\)]+)\)\)',    'new':'(\\1)',    'comment':'((A)) => (A)'})
        self.rules_unpack.append({'pat':'([\(\|])\((#)((\|#)+)\)\|(#)?',  
                        'new':'\\1\\2\\3|\\5',    
                        'comment':'(A|B|C|...|D)|X => A|B|...|D|X'})
        self.rules_unpack.append({'pat':'^\((#)((\|#)+)\)\|(#)?',  
                        'new':'\\1\\2|\\4',    
                        'comment':'^(A|B|C|...|D)|X => A|B|...|D|X'})
        self.rules_unpack.append({'pat':'(#)?\|\((#)((\|#)+)\)([\)\|])',    
                        'new':'\\1|\\2\\3\\5',    
                        'comment':'Y|(A|B|C|...|D) => Y|A|B|...|D'})
        self.rules_unpack.append({'pat':'(#)?\|\((#)((\|#)+)\)$',    
                        'new':'\\1|\\2\\3',    
                        'comment':'Y|(A|B|C|...|D) => Y|A|B|...|D'})
        self.rules_unpack.append({'pat':'\|\((#)((\|#)+)\)\|',    
                        'new':'|\\1\\2|',    'comment':'|(A|B|C|...|D)| => |A|B|...|D|'})
        
        # 分配律规则 (A|B)C => (AC|BC)
        self.rules_unpack.append({'pat':'(#)\((#)\|((#\|)*)(#)?\)',    
                        'new':'(\\1\\2|\\1(\\3\\5))',    'comment':'X(A|B|C|D|E) => (XA|X(B|C|D|E))'}) #左分配
        self.rules_unpack.append({'pat':'\((#)((\|#)*)\|(#)?\)(#)',    
                        'new':'((\\1\\2)\\5|\\4\\5)',    'comment':'(A|B|C|D|E)X => ((A|B|C|D)X|EX)'}) #右分配
        
        # 结合律规则 (A|B)(C|D) => (AC|AD|BC|BD); (A|B|C|D)(X|Y|Z|V) => (AX|(B|C|D)(Y|Z|V)|A(Y|Z|V)|(B|C|D)X)
        self.rules_unpack.append({'pat':'\((#)\|((#\|)*(#)?)\)\((#)\|((#\|)*(#)?)\)',
                        'new':'(\\1\\5|\\1(\\6)|(\\2)\\5|(\\2)(\\6))',
                        'comment':'(A|B|C|D)(X|Y|Z|V) => (AX|(B|C|D)(Y|Z|V)|A(Y|Z|V)|(B|C|D)X)'})
        
        for rrr in self.rules_unpack:
            rrr['pat'] = rrr['pat'].replace('#', chr_pat)
        
        return
        

    
    def unpack_term(self, fct_txt):
        '''
            根据指标通配符公式 进行演绎，尽可能多的穷举出各种指标文本形式
            '|' 相当于 加法运算
            词和词之间没有符号，但存在拼接关系，且拼接优先于加法，相当于除法运算
            括号跟四则运算的括号类似
            举一个变态的例子：((右|)(颊(粘|黏)膜)|口腔)溃疡
                           => ((右+?)/(颊/(粘+黏)/膜)+口腔)/溃疡
                           => ((右+?)/((颊/粘+颊/黏)/膜)+口腔)/溃疡
                           => ((右+?)/(颊/粘/膜+颊/黏/膜)+口腔)/溃疡
                           => ((右+?)/(颊/粘/膜+颊/黏/膜)/溃疡+口腔/溃疡)
                           => ((右+?)/(颊/粘/膜/溃疡+颊/黏/膜/溃疡)+口腔/溃疡)
                           => ((右+?)/(颊粘膜溃疡+颊黏膜溃疡)+口腔溃疡)
                           => (((右+?)/颊粘膜溃疡+(右+?)/颊黏膜溃疡)+口腔溃疡)
                           => ((右/颊粘膜溃疡+颊粘膜溃疡+右/颊黏膜溃疡+颊黏膜溃疡)+口腔溃疡)
                           => ((右颊粘膜溃疡+颊粘膜溃疡+右颊黏膜溃疡+颊黏膜溃疡)+口腔溃疡)
                           => 右颊粘膜溃疡+颊粘膜溃疡+右颊黏膜溃疡+颊黏膜溃疡+口腔溃疡
        '''
        fct_txt = re.sub('[^一-～\w\d\(\)\|]','',fct_txt)
        if '(' not in fct_txt: return self.txt2lst(fct_txt)
        if ')' not in fct_txt: return self.txt2lst(fct_txt)
        new_txt = re.sub(self.rule0['pat'], self.rule0['new'], fct_txt)        
        
        print('unpack_term raw:',new_txt)
        last_txt = new_txt
        for i in range(500):
            for rrr in self.rules_unpack:
                old_txt = new_txt
                new_txt = re.sub(rrr['pat'], rrr['new'], old_txt)
                if old_txt != new_txt:
                    print(rrr['comment'])
                    print('        ', new_txt)
            if new_txt == last_txt: break
            last_txt = new_txt
        
        return self.txt2lst(new_txt)
    
    def txt2lst(self,txt):
        if '|' not in txt: return [txt]
        if '(' in txt: 
            print('txt2lst: bad format:', txt)
            return []
        if ')' in txt: 
            print('txt2lst: bad format:', txt)
            return []
        fct_lst = list(set(txt.split('|')))
        return fct_lst

if __name__ == "__main__":
    ff = TermFormular()
    test_txts = []
    test_txts.append('肺(上叶)(模糊灶|((条片|高密度)影))')
    test_txts.append('((右)(颊(粘|黏)膜)|口腔)溃疡')
    test_txts.append('(面部)(集中分布|针尖样|红色)皮疹')
    for txt in test_txts[:]:
        print('=='*20)
        print(txt)
        new_txt = ff.unpack_term(txt)
        print(new_txt)